package com.example.demo.utils;

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.IOException;
import java.io.UncheckedIOException;
import java.util.List;
import java.util.Map;

/**
 * @author shenb
 * @date 2022-09-15 10:51
 */
public class JsonUtils {
    private static final ObjectMapper mapper = new ObjectMapper();

    static {
        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    }

    public static String toJson(Object any) {
        if (any == null) {
            return null;
        }
        try {
            return mapper.writeValueAsString(any);
        } catch (IOException e) {
            throw new UncheckedIOException("obj to json error: " + any, e);
        }
    }

    public static <T> T fromJson(String json, Class<T> clz) {
        if (json == null) {
            return null;
        }
        try {
            return mapper.readValue(json, clz);
        } catch (IOException e) {
            throw new UncheckedIOException("json to object error, class type: " + clz, e);
        }
    }

    public static <T> List<T> fromJsonAsList(String json, Class<T> itemClz) {
        if (json == null) {
            return null;
        }
        try {
            return mapper.readValue(json,
                    mapper.getTypeFactory().constructCollectionType(List.class, itemClz));
        } catch (IOException e) {
            throw new UncheckedIOException("json to list error, generic type: " + itemClz, e);
        }
    }

    public static <K, V> Map<K, V> fromJsonAsMap(String json, Class<K> keyClz, Class<V> valueClz) {
        if (json == null) {
            return null;
        }
        try {
            return mapper.readValue(json,
                    mapper.getTypeFactory().constructMapType(Map.class, keyClz, valueClz));
        } catch (IOException e) {
            throw new UncheckedIOException("json to map error, generic key type: " + keyClz + ", generic value type: " + valueClz, e);
        }
    }
}
